var db = require('nedb')
class nedb {
  constructor (database = 'data') {
    this.db = new db({ filename: `data/${database}`, autoload: true })
  }
  /**
   * @function 添加数据
   * @param {Object} data 要插入的数据
   */
  insert (data) {
    return new Promise((resolve, reject) => {
      this.db.insert(data, (err, newDoc) => {
        if (err) {
          reject (err)
          return false
        }
        resolve()
      })
    })
  }
  /**
   * @function 插入唯一的数据
   * @param {Object} data 要插入的数据
   * @param {Object} query 不允许重复的条件
   * @param {Boolean} cover 是否允许覆盖
   */
  insertOnlyOne (data, query, cover = false) {
    return new Promise((resolve, reject) => {
      this.findOr(query).then((result) => {
        if (result.length > 1) {
          // 已经存在数据，不在是唯一的数据, 判断是否允许覆盖，如果允许则删除后添加，否则返回错误
          if (cover) {
            this.update({_id: result[0]._id}, data).then(() => {
              resolve()
            }, (err) => {
              reject(err)
            })
          } else {
            reject('已经存在同样的数据')
          }
        } else {
          this.insert(data).then(() => {
            resolve()
          }, (err) => {
            reject(err)
          })
        }
      }, (err) => {
        reject(err)
      })
    })
  }
  /**
   * @function 查找数据
   * @param {Object} query 要查找的数据
   * @description 参考文档https://www.npmjs.com/package/nedb
   */
  find (query) {
    return new Promise((resolve, reject) => {
      this.db.find(query, function (err, docs) {
        if (err) {
          reject(err)
          return false
        }
        resolve(docs)
      })
    })
  }
  /**
   * @function 多条件或查询
   * @param {Object} query 要查找的数据
   * @description 参考文档https://www.npmjs.com/package/nedb
   */
  findOr (query) {
    return new Promise((resolve, reject) => {
      // 拆封query， {a: 1, b:2}拆成[{a: 1}, {b: 2}]
      let _arr = []
      for (let i in query) {
        _arr.push(
          {[i] : query[i]}
        )
      }
      this.db.find({ $or: _arr }, function (err, docs) {
        if (err) {
          reject(err)
          return false
        }
        resolve(docs)
      })
    })
  }
  /**
   * @function 更新数据
   * @param {Object} query 查询条件
   * @param {Object} data 要更新的数据
   * @param {Objcet} option 配置的选项 参考文档
   * @description
   * option：object类型。muti(默认false)，是否允许修改多条文档；upsert(默认为false)，如果query没有匹配到结果集，有两种情况需要考虑，一个是update是一个简单的对象(不包含任何修饰符)，另一种情况是带有修饰符，对第一种情况会直接将该文档插入，对第二种情况会将通过修饰符更改后的文档插入； 
   */
  update (query, data, option = {}) {
    return new Promise((resolve, reject) => {
      this.db.update(query, data, option, (err, numReplaced) => {
        if (err) {
          reject(err)
          return false
        }
        resolve(numReplaced)
      })
    })
  }
  /**
   * @function 删除数据
   * @param {Object} query 查询条件
   * @param {isMulti} isMulti 是否允许多条数据进行操作，默认false
   */
  remove (query, isMulti = false) {
    return new Promise((resolve, reject) => {
      this.db.remove(query, {multi: isMulti}, (err, numRemoved) => {
        if (err) {
          reject(err)
          return false
        }
        resolve(numRemoved)
      })
    })
  }
  /**
   * @function 删除所有数据
   */
  removeAll () {
    return new Promise((resolve, reject) => {
      this.remove({},true).then(() => {
        resolve()
      }, (err) => {
        reject(err)
      })
    })
  }
}
module.exports = nedb